package db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class MySQLConnection {

    private boolean verbose;
    private String dbHost, dbSchema, dbUser, dbPass;
    private Connection conn = null;
    
    public static String usage(){
        return "To connect to a databse, provide four arguments: HOST SCHEMA USER [PASS optional]\n"
                + "Default mode is silent; to turn on verbose mode, include 'v' in front of the other parameters.";
    }

    public MySQLConnection(String... args){
        if(args.length==3)
            init(args[0],args[1],args[2], "",false);
        else if(args.length==4)
            init(args[0],args[1],args[2],args[3],false);
        else
            init(args[1],args[2],args[3],args[4],args[0].contains("v"));
    } 
    
    private void init(String host, String schema, String user, String pass, boolean verbose) {
        this.verbose = verbose;
        this.dbHost = host;
        this.dbSchema = schema;
        this.dbUser = user;
        this.dbPass = pass;
        open();
    }

    protected final PreparedStatement getPS(String query) {
        try {
            return conn.prepareStatement(query);
        } catch (Exception e) {
            return null;
        }
    }

    protected final void open() {
        String connString = "jdbc:mysql://" + dbHost + "/" + dbSchema + "?user=" + dbUser + "&password=" + dbPass+"";
        String hiddenString = "jdbc:mysql://" + dbHost + "/" + dbSchema + "?user=" + dbUser + "&password=<length:" + dbPass.length()+">\n"
                + "(real password omitted, character count included for troubleshooting)";
        try {
            DriverManager.setLoginTimeout(5);
            conn = DriverManager.getConnection(connString);

            if (verbose) {
                System.out.println("Connected " + hiddenString);
            }
        } catch (SQLException e) {
            if (verbose) {
                System.out.println("NOT connected: " + hiddenString);
                System.out.println("MySQL Connection and Query Manager could not be configured: \n\t" + e.getMessage() + "\n\terror code:" + e.getErrorCode());
                e.printStackTrace();
            }
        }
    }

    /**
     * Check the health of the manager
     * @return true iff underlying connector is properly configured
     */
    protected final boolean isOk() {
        try {
            return conn != null && conn.isValid(2);
        } catch (SQLException ex) {
            return false;
        }
    }

    /**
     * Execute a SELECT query and return the resulting ResultSet.
     * @param ps - prepared statement for the query
     * @return null if the connection is ill, or if something went wrong.
     * A description of the runtime exception will be given in the case of the latter.
     */
    protected final ResultSet select(PreparedStatement ps) {
        if (!isOk()) {
            open();
        }
        ResultSet out = null;
        try {
            out = ps.executeQuery();
        } catch (SQLException e) {
            if (verbose) {
                System.out.println("Failed to select:\n" + e.getMessage());
            }
        }

        return out;

    }

    /**
     * A convenience method of sorts - equivalent to constructing a prepared statement from the query and calling selectVerbose(PreparedStatement) on it.
     * @param query
     * @return
     */
    protected final ResultSet execute(String query) {
        if (!isOk()) {
            open();
        }
        PreparedStatement ps = null;

        try {
            ps = conn.prepareStatement(query);
        } catch (SQLException ex) {
            System.out.println("Failed to prepare " + query + "\n" + ex.getMessage());
        }

        ResultSet out = null;
        if (ps != null) {
            try {
                if (ps.execute())
                    return ps.getResultSet();
            } catch (SQLException e) {
                System.out.println("Failed to select " + query + "\n" + e.getMessage());
            }
        }
        return out;
    }


}